package com.zhy.deploy.executor.defaultImpl;

import cn.hutool.core.util.StrUtil;
import com.zhy.deploy.config.BuildMetadata;
import com.zhy.deploy.config.MavenConfig;
import com.zhy.deploy.executor.AbstractExecutor;
import com.zhy.deploy.websocket.SocketMessage;
import org.apache.maven.shared.invoker.*;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class DefaultMavenExecutor extends AbstractExecutor {

    private SocketMessage socketMessage;

    public DefaultMavenExecutor(BuildMetadata metadata) {
        super(metadata);
        this.socketMessage = metadata.getMessage();
    }


    public void execute() throws Exception{

        MavenConfig mavenConfig = metadata.getMavenConfig();

        Invoker invoker = createInvoker(mavenConfig);

        InvocationRequest request = new DefaultInvocationRequest();
        request.setBaseDirectory(new File(mavenConfig.getWorkDir()));

        List<String> goals = mavenConfig.getGoals();
        if(CollectionUtils.isEmpty(goals)){
            goals = Arrays.asList("package");
        }
        request.setGoals(goals);
        request.setDebug(false);

        String pomFileName = mavenConfig.getPomFileName();
        if(StrUtil.isEmpty(pomFileName)){
            pomFileName = "pom.xml";
        }
        request.setPomFileName(pomFileName);

        String opts = mavenConfig.getOpts();
        if(StrUtil.isNotEmpty(opts)){
            request.setMavenOpts(opts);
        }

        socketMessage.info("开始编译");
        InvocationResult result = invoker.execute(request);

        if (result.getExitCode() != 0) {
            if (result.getExecutionException() != null) {
                socketMessage.error("Failed to publish site.", result.getExecutionException());
                throw new MavenInvocationException("Failed to publish site.", result.getExecutionException());
            } else {
                socketMessage.error("Failed to publish site. Exit code: " + result.getExitCode());
                throw new MavenInvocationException("Failed to publish site. Exit code: " + result.getExitCode());
            }
        }else{
            socketMessage.info("编译结束");
        }
    }

    private Invoker createInvoker(MavenConfig config) throws MavenInvocationException {
        Invoker newInvoker = new DefaultInvoker();

        String mavenHomeDir = config.getMavenHomeDir();
        if(StrUtil.isEmpty(mavenHomeDir)){
            mavenHomeDir = System.getenv("MAVEN_HOME");
        }
        if(StrUtil.isEmpty(mavenHomeDir)){
            socketMessage.error("请设置MAVEN_HOME环境变量或设置maven-home-dir系统参数");
            throw new MavenInvocationException("请设置MAVEN_HOME环境变量或设置maven-home-dir系统参数");
        }

        newInvoker.setMavenHome(new File(mavenHomeDir));

        String workDir = config.getWorkDir();
        if(StrUtil.isEmpty(workDir)){
            String projectName = metadata.getProjectName();
            String workspace = metadata.getWorkspace();
            workDir = new StringBuffer().append(workspace).append(File.separator).append(projectName).toString();
            config.setWorkDir(workDir);
        }

        newInvoker.setWorkingDirectory(new File(config.getWorkDir()));
        newInvoker.setLogger(socketMessage);
        newInvoker.setOutputHandler(new InvocationOutputHandler() {
            public void consumeLine(String s) throws IOException {
                if(Objects.nonNull(socketMessage) ){
                    socketMessage.info(s);
                }
            }
        });
        newInvoker.setErrorHandler(new InvocationOutputHandler() {
            @Override
            public void consumeLine(String s) throws IOException {
                if(Objects.nonNull(socketMessage) ){
                    socketMessage.error(s);
                }
            }
        });
        return newInvoker;
    }


}
